<?php
/**
 * CreateUser: zlh
 * CreateTime: 2022/1/18 10:48
 * Remark:该类主要实现钉钉部门和用户的相关操作
 */
namespace App\Tools\DingTalk;

use AlibabaCloud\SDK\Dingtalk\Voauth2_1_0\Dingtalk;
use App\Consts\DingTalkConsts\DingTalkConfigConsts;
use App\Consts\ResponseConsts\ResponseStatusConsts;
use App\Func\AppFunc;
use App\Func\ResponseFunc;
use DingTalkClient;
use DingTalkConstant;
use \Exception;
use Darabonba\OpenApi\Models\Config;
use AlibabaCloud\SDK\Dingtalk\Voauth2_1_0\Models\GetAccessTokenRequest;
use Illuminate\Http\Exceptions\HttpResponseException;
use JetBrains\PhpStorm\Pure;
use OapiSnsGetuserinfoBycodeRequest;
use OapiUserCountRequest;
use OapiUserGetbyunionidRequest;
use OapiUserListidRequest;
use OapiV2DepartmentGetRequest;
use OapiV2DepartmentListsubRequest;
use OapiV2UserGetRequest;

class DingTalkDeptUserFacade extends BaseDingTalk
{

    /**
     * 获取员工详情
     * @param $userId
     * @return \$1|false|mixed|\ResultSet|\SimpleXMLElement
     */
    public static function getUserInfoByUserId($userId)
    {
        $userGetRequest = new OapiV2UserGetRequest();
        $userGetRequest->setUserid($userId);
        $bestUrl = "https://oapi.dingtalk.com/topapi/v2/user/get";
        try {
            $userInfo = self::getDingTalkOldClient()->execute($userGetRequest,self::getAccessToken(),$bestUrl);
        }catch (Exception $err){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "钉钉客户端错误:".$err->getMessage(),
                ResponseStatusConsts::INTERNAL_SERVER_ERROR_500_RESPONSE_STATUS
            ));
        }
        if(isset($userInfo->errcode) && $userInfo->errcode){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "钉钉客户端错误:".$userInfo->errmsg,
                ResponseStatusConsts::INTERNAL_SERVER_ERROR_500_RESPONSE_STATUS
            ));
        }
        return $userInfo->result;
    }


    # ========================================旧版========================================

    /**
     * 获取钉钉部门
     * @return array|\Illuminate\Http\JsonResponse
     */
    public static function getDepartmentList() : array | \Illuminate\Http\JsonResponse
    {
        $req = new OapiV2DepartmentListsubRequest;
        $bestUrl = "https://oapi.dingtalk.com/topapi/v2/department/listsub";
        try {
            $departmentList = self::getDingTalkOldClient()->execute($req, self::getAccessToken(),$bestUrl);
        }catch (Exception $err){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "钉钉客户端错误".$err->getMessage(),
                ResponseStatusConsts::INTERNAL_SERVER_ERROR_500_RESPONSE_STATUS
            ));
        }

        if(isset($departmentList->errcode) && $departmentList->errcode){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "钉钉客户端错误:".$departmentList->errmsg,
                ResponseStatusConsts::INTERNAL_SERVER_ERROR_500_RESPONSE_STATUS
            ));
        }

        return $departmentList->result;
    }

    /**
     * 通过部门id获取用户列表
     * @param int $deptId
     * @return array|\Illuminate\Http\JsonResponse
     */
    public static function getUserListIdsByDeptId(int $deptId): array | \Illuminate\Http\JsonResponse
    {
        $req = new OapiUserListidRequest;
        $bestUrl = "https://oapi.dingtalk.com/topapi/user/listid";
        $req->setDeptId($deptId);
        try {
            $userList = self::getDingTalkOldClient()->execute($req,self::getAccessToken(),$bestUrl);
        }catch (Exception $err){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "钉钉客户端错误:".$err->getMessage(),
                ResponseStatusConsts::INTERNAL_SERVER_ERROR_500_RESPONSE_STATUS
            ));
        }
        if(isset($userList->errcode) && $userList->errcode){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "钉钉客户端错误:".$userList->errmsg,
                ResponseStatusConsts::INTERNAL_SERVER_ERROR_500_RESPONSE_STATUS
            ));
        }
        return $userList->result->userid_list;
    }

    /**
     * @param string $deptId
     * @return array|\Illuminate\Http\JsonResponse
     */
    public static function getDepartmentInfoByDepartmentId(string $deptId)
    {
        $req = new OapiV2DepartmentGetRequest;
        $bestUrl = "https://oapi.dingtalk.com/topapi/v2/department/get";
        $req->setDeptId($deptId);
        try {
            $departInfo = self::getDingTalkOldClient()->execute($req,self::getAccessToken(),$bestUrl);
        }catch (Exception $err){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "钉钉客户端错误:".$err->getMessage(),
                ResponseStatusConsts::INTERNAL_SERVER_ERROR_500_RESPONSE_STATUS
            ));
        }
        if(isset($userList->errcode) && $userList->errcode){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "钉钉客户端错误:".$userList->errmsg,
                ResponseStatusConsts::INTERNAL_SERVER_ERROR_500_RESPONSE_STATUS
            ));
        }
        return $departInfo->result;
    }

    /**
     * 获取钉钉员工数量
     * @param bool $flag 当 flag 为 false时默认包含未激活钉钉员工，为 true只包含了激活员工的数量
     * @return int
     */
    public static function getUserCountByFlag(bool $flag = true): int
    {
        $req = new OapiUserCountRequest;
        $bestUrl = "https://oapi.dingtalk.com/topapi/user/count";
        $req->setOnlyActive($flag);
        try {
            $userCount = self::getDingTalkOldClient()->execute($req,self::getAccessToken(),$bestUrl);
        }catch (Exception $err){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "钉钉客户端错误:".$err->getMessage(),
                ResponseStatusConsts::INTERNAL_SERVER_ERROR_500_RESPONSE_STATUS
            ));
        }
        if(isset($userCount->errcode) && $userCount->errcode){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "钉钉客户端错误:".$userCount->errmsg,
                ResponseStatusConsts::INTERNAL_SERVER_ERROR_500_RESPONSE_STATUS
            ));
        }
        return $userCount->result->count;
    }

    /**
     * 扫码登录
     * @param $code
     * @return \$1|false|mixed|\ResultSet|\SimpleXMLElement
     */
    public static function getDingTalkScanOrCodes($code){
        $bestUrl = "https://oapi.dingtalk.com/sns/getuserinfo_bycode";
        $appid = AppFunc::getDingTalkConfig()::DING_TALK_LOGIN_APP_ID;
        $secret = AppFunc::getDingTalkConfig()::DING_TALK_LOGIN_APP_SECRET;
        $userSnsGetRequest = new OapiSnsGetuserinfoBycodeRequest();
        $userSnsGetRequest->setTmpAuthCode($code);
        try {
            $userSnsGetInfo = DingTalkApprovalProcess::getDingTalkOldClient()->executeWithAccessKey($userSnsGetRequest,$bestUrl,$appid,$secret);
        }catch (Exception $err){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "169 钉钉客户端错误:".$err->getMessage(),
                ResponseStatusConsts::INTERNAL_SERVER_ERROR_500_RESPONSE_STATUS
            ));
        }
        if(isset($userSnsGetInfo->errcode) && $userSnsGetInfo->errcode){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "177 钉钉客户端错误:".$userSnsGetInfo->errmsg,
                ResponseStatusConsts::INTERNAL_SERVER_ERROR_500_RESPONSE_STATUS
            ));
        }
        return $userSnsGetInfo->user_info->unionid;
    }


    /**
     * 通过钉钉 UnionId 获取用户id
     * @param $unionId
     * @return \$1|false|mixed|\ResultSet|\SimpleXMLElement
     */
    public static function getDingTalkUserIdByUnionId($unionId){
        $req = new OapiUserGetbyunionidRequest;
        $req->setUnionid($unionId);
        $bestUrl = "https://oapi.dingtalk.com/topapi/user/getbyunionid";
        try {
            $userId = self::getDingTalkOldClient()->execute($req,self::getAccessToken(),$bestUrl);
        }catch (Exception $err){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "200 钉钉客户端错误:".$err->getMessage(),
                ResponseStatusConsts::INTERNAL_SERVER_ERROR_500_RESPONSE_STATUS
            ));
        }
        if(isset($userId->errcode) && $userId->errcode){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "208 钉钉客户端错误:".$userId->errmsg,
                ResponseStatusConsts::INTERNAL_SERVER_ERROR_500_RESPONSE_STATUS
            ));
        }
        return $userId->result->userid;
    }

    /**
     * 通过钉钉ID获取用户的unionid
     * @param $userId
     * @return \$1|false|mixed|\ResultSet|\SimpleXMLElement
     */
    public static  function getDingTalkUserInfoByUserId($userId){
        $req = new OapiV2UserGetRequest;
        $req->setUserid($userId);
        $bestUrl = "https://oapi.dingtalk.com/topapi/v2/user/get";
        try {
            $userInfo = self::getDingTalkOldClient()->execute($req,self::getAccessToken(),$bestUrl);
        }catch (Exception $err){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "228 钉钉客户端错误:".$err->getMessage(),
                ResponseStatusConsts::INTERNAL_SERVER_ERROR_500_RESPONSE_STATUS
            ));
        }
        if(isset($userInfo->errcode) && $userInfo->errcode){
            throw new HttpResponseException(ResponseFunc::returnJson(
                'error',
                '',
                "236 钉钉客户端错误:".$userInfo->errmsg,
                ResponseStatusConsts::INTERNAL_SERVER_ERROR_500_RESPONSE_STATUS
            ));
        }
        return $userInfo->result;
    }


}